#!/usr/bin/env bash

# uz tool is to analyze files, create proper folder and
# then decompress files
#
#
set -u
# set -x # Uncomment to debug this script 
# set -n # Uncomment to check command syntax without any execution

UZ_REVISON="v0.0.01"
#UZ_E_BADARGS=65 
UZ_E_NOFILE=66
UZ_E_EMPTYFILE=67
UZ_E_READFILE=68
UZ_E_USER_INTERRUPT=13
UZ_PROG=""
UZ_OPTION=""
UZ_DEBUG=true

ext=""
name=""
function fatal 
{ 
   echo "$0: fatal error:" "$@" >&2 # messages to standard error 
   exit 1 
}
uzname=`basename ${0##*/}`
function usage
{ 
   echo ""
   echo " Usage: $uzname filename" >&2
   echo ""
   exit 0 
}

UZ_MAXARGS="1"
# Number of command-line arguments.
function checkArguments 
{ 
   #echo "Total arguments = $1"
   if [ "$1" -ne "$UZ_MAXARGS" ] || [ -z "$1" ]; then
      usage
   fi
   return 0
}

TEMPFILE=temp.$$
trap `rm -f $TEMPFILE; exit $UZ_E_USER_INTERRUPT` TERM INT 
# Cleans up the temp file if script interrupted by control-c.

# filename validation
function validateName
{ 
   if [ ! -e "$1" ]; then       # Check if file exists.
      echo "File not found!"
      exit "$UZ_E_NOFILE"
   fi
   if [ ! -s "$1" ]; then       # Check if zero size 
      echo "File is empty!"
      exit "$UZ_E_EMPTYFILE"
   fi
   if [ ! -r "$1" ]; then       # Check if read permission
      echo "File is not read!"
      exit "$UZ_E_READFILE"
   fi

   return 0
}
function getFileExtension
{ 
   #echo "Full filename = $1"
   local fullpath="$1"
   local filename="${fullpath##*/}"                        ## Strip longest match of */ from start
   #echo "filename = $filename"
   name=${filename%%.*}
   #echo "name = $name"
   local dir="${fullpath:0:${#fullpath} - ${#filename}}"   ## Substring from 0 thru pos of filename
   #echo "dir = $dir"
   local base="${filename%.[^.]*}"                         ## Strip shortest match of . plus at least one non-dot char from end
   #echo "base1 = $base"
   base=`echo "$base" | cut -d'.' -f2`
   #echo "base2 = $base"
   #ext="${filename:${#base} + 1}"                    ## Substring from len of base thru end
   ext="${filename:${#base} }"                    ## Substring from len of base thru end
   #echo "ext = $ext"
   if [[ -z "$base" && -n "$ext" ]]; then            ## If we have an extension and no base, it's really the base
      base=".$ext"
      ext=""
   fi
   if [ -z "$dir" ]; then
      dir="./"
   fi
   #echo -e "$fullpath:\n\tdir  = \"$dir\"\n\tbase = \"$base\"\n\text  = \"$ext\""
   return 0
}
function debug 
{ 
   if [ "$UZ_DEBUG" = "true" ]; then 
      if [ "$1" = "on"  -o "$1" = "ON" ]; then 
         set -x 
      else 
         set +x 
      fi 
   fi 
} 

function failed
{ 
    if [ "$1" -ne "0" ]; then 
      echo "Failed. Exiting."
      exit 1 
    fi 
    echo "ok" 
} 

#
# Check available tools in current system
# 
function checkProperTool
{ 
   if [ -z "$1" ]; then
      fatal "checkProperTool: NULL parameter!" 
   fi
   local tool="$1"
   #echo "tool = $tool"
   echo -e "Checking $tool...\c"
   for path in ${PATH//:/ }; do
      #echo "$path/$tool"
      if [ ! -e "$path/$tool" ]; then   # if file exists 
         #echo "file not found!"
         continue
         #failed "1"
      fi
      if [ ! -f "$path/$tool" ]; then   # file is a regular file
         #echo "abnormal file!"
         continue
         #failed "1"
      fi
      if [ ! -r "$path/$tool" ]; then
         #echo "read failed!"
         continue
         #failed "1"
      fi
      if [ -x "$path/$tool" ]; then  
         failed "0"
         return 0
      fi
   done
   return 1 
}
function checkAvailableProgram
{ 
   #echo "Total arguments = $1"
   if [ -z "$1" ]; then
      fatal "checkAvailableProgram failed!" 
   fi
   local type="$1"
   local stat
   #local program
   echo "type = $type"
   case "$type" in
      .tar)
         option="tar"
         checkProperTool "tar"
         stat="$?"
         if [ "$stat" -eq "0" ]; then
            UZ_PROG=tar
            UZ_OPTION="-xvf"
            ## Untar files in specified Directory ##
            # tar -xvf public_html.tar -C /home/public_html/videos/
            # Verification/Test tar tvfW tecmint-14-09-12.tar
         else
            checkProperTool "gzip"
            stat="$?"
            failed "$stat"
            if [ "$stat" -eq "0" ]; then
               UZ_PROG=gzip
               UZ_OPTION="-cd"
               UZ_OPTIONX="xvf -"
            fi
         fi
      tar.gz)
         option="tar"
         checkProperTool "tar"
         stat="$?"
         if [ "$stat" -eq "0" ]; then
            UZ_PROG=tar
            UZ_OPTION="-zxvf"
         else
            checkProperTool "gzip"
            stat="$?"
            failed "$stat"
            if [ "$stat" -eq "0" ]; then
               UZ_PROG=gzip
               UZ_OPTION="-cd"
               UZ_OPTIONX="xvf -"
            fi
         fi
         ;;
      .gz)
         option="gzip"         # File compressed by gzip
         checkProperTool "gzip"
         stat="$?"
         if [ "$stat" -eq "0" ]; then
            UZ_PROG=gzip
            UZ_OPTION="-d"
         else
            checkProperTool "gunzip"
            stat="$?"
            failed "$stat"
            if [ "$stat" -eq "0" ]; then
               UZ_PROG=gunzip
               UZ_OPTION=""
            fi
         fi
         ;;
      .bz2)
         option="bzip2/bunzip2"  # File compressed by bzip2
         option="bzip2"  
         checkProperTool "bzip2"
         stat="$?"
         if [ "$stat" -eq "0" ]; then
            UZ_PROG=bzip2
            UZ_OPTION="-d"
         else
            option="bunzip2"  
            checkProperTool "bunzip2"
            stat="$?"
            failed "$stat"
            if [ "$stat" -eq "0" ]; then
               UZ_PROG=bunzip2
               UZ_OPTION=""      # No options
            fi
         fi
         ;;
      tar.bz2)
         option="tar"
         checkProperTool "tar"
         stat="$?"
         if [ "$stat" -eq "0" ]; then
            UZ_PROG=tar
            UZ_OPTION="-vxjf"
         else
            checkProperTool "gzip"
            stat="$?"
            failed "$stat"
            if [ "$stat" -eq "0" ]; then
               UZ_PROG=gzip
               UZ_OPTION="-cd"
               UZ_OPTIONX="xvf -"
            fi
         fi
         ;;
      tbz2)
         option="bunzip2"  
         checkProperTool "bunzip2"
         stat="$?"
         if [ "$stat" -eq "0" ]; then
            UZ_PROG=bunzip2
            UZ_OPTION="-k -c"
         else
            option="bzip2"  
            checkProperTool "bzip2"
            stat="$?"
            failed "$stat"
            if [ "$stat" -eq "0" ]; then
               UZ_PROG=bzip2
               UZ_OPTION="-d"
            fi
         fi
      .Z)
         option="uncompress"
         checkProperTool "uncompress"
         stat="$?"
         if [ "$stat" -eq "0" ]; then
            UZ_PROG=uncompress
            UZ_OPTION=""
         fi
         ;;
      z)
         option="pack"
         ;;
      zip)
         option="unzip"
         ;;
      rar)
         option="rar"
         ;;
      tgz)
         option="tar"
         ;;
      Rar)
         option="Rar"
         ;;
      *)
         fatal "checkAvailableProgram: Have not supported yet!" 
         ;;         
   esac
   #echo "option = $option"
   return 0
}
# directory validation
function checkProperDir
{ 
   if [[ -z "$1" && "$1" = '' ]]; then
      fatal "Directory name is empty!"
   fi
   if [ -d "$1" ]; then       # Check if dir exists.
      echo -e "Deleting old directory $1...\c"
      rm -rf "$1" > /dev/null 2>&1
      failed "$?"
   fi
   if [ -f "$1" ]; then       # Check if file exists.
      echo -e "Deleting old file $1...\c"
      rm -f "$1" > /dev/null 2>&1
      failed "$?"
   fi
}
 
# Structured programming: 
# entire program logic modularized in functions. 
# ================
checkArguments "${#}"
validateName "${1}"
getFileExtension "${1}"
#echo "name = $name"
#echo "ext = $ext"
checkAvailableProgram "${ext}"
#echo "Program = $UZ_PROG"
#echo "Option = $UZ_OPTION"
checkProperDir "$name"
mkdir "$name"
cd "$name"

echo "Decompress tool processing..."
"$UZ_PROG" "$UZ_OPTION" "../${1}"

echo "status = $?"
#echo "uz $UZ_REVISION"
# ================

exit 0

